package com.byron.media.server.model;

import com.byron.media.server.utils.MediaType;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

import static com.byron.media.server.MediaServer.MTU;

public class DataFactory {

    private Queue<MediaData> freeMediaQueue = new ConcurrentLinkedQueue<>();

    /**
     * 从缓存中创建媒体数据
     */
    public MediaData createData(int length) {
        MediaData mediaData = freeMediaQueue.poll();
        if(mediaData == null){
//            return new MediaData((byte) 0, (byte) 0, 0l, new byte[length], length);
            return new MediaData((byte) 0, (byte) 0, 0, new byte[MTU], length);
        }
        mediaData.setLength(length);
        return mediaData;
    }

    /**
     * 从缓存中创建媒体数据
     */
    public List<MediaData> createData(byte channel, long id, byte[] data, int length, int mediaType) {
        List<MediaData> mediaList = new ArrayList<>();
        if (data.length > MTU) {
            int count = (int) Math.floor((float)data.length / MTU);
            int left = data.length % MTU;

            int read = 0;

//            byte type = 0;
            for (int i = 0; i < count; i++) {
                byte type = 0;
                if (mediaType == MediaType.H264) {
                    type = MediaType.putH264(type);
                } else {
                    type = MediaType.putAAC(type);
                }
                byte[] temp = new byte[MTU];
                System.arraycopy(data, read, temp, 0, MTU);
                read += MTU;

                if (i == 0) {
                    type = MediaType.putStart(type);
                } else if (i == count - 1 && left == 0) {
                    type = MediaType.putEnd(type);
                } else {

                }
                MediaData mediaData = createData(temp.length);
                mediaData.setChannel(channel);
                mediaData.setType(type);
                mediaData.setSeq(id);
                mediaData.setData(data);
                mediaList.add(mediaData);
            }
            if (left != 0) {
                byte type = 0;
                if (mediaType == MediaType.H264) {
                    type = MediaType.putH264(type);
                } else {
                    type = MediaType.putAAC(type);
                }
                byte[] temp = new byte[left];
                System.arraycopy(data, read, temp, 0, left);
                read += left;
                type = MediaType.putEnd(type);

                MediaData mediaData = createData(temp.length);
                mediaData.setChannel(channel);
                mediaData.setType(type);
                mediaData.setSeq(id);
                mediaData.setData(data);
                mediaList.add(mediaData);
            }
        } else {
            byte type = 0;
            type = MediaType.putEnd(type);
            type = MediaType.putStart(type);
            if (mediaType == MediaType.H264) {
                type = MediaType.putH264(type);
            } else {
                type = MediaType.putAAC(type);
            }

            MediaData mediaData = createData(length);
            mediaData.setChannel(channel);
            mediaData.setType(type);
            mediaData.setSeq(id);
            mediaData.setData(data);
            mediaList.add(mediaData);
        }
        return mediaList;
    }

    /**
     * 重新把用完的mediaData 推回到队列中
     */
    public void offerData(MediaData mediaData){
        freeMediaQueue.offer(mediaData);
    }

    /**
     * 批量把用完的mediaData 推回到队列中
     * @param freeMediaData
     */
    public void offerDataBatch(Queue<MediaData> freeMediaData) {
        freeMediaQueue.addAll(freeMediaData);
    }

}
